import java.util.ArrayList;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import javax.swing.JFileChooser;
import javax.swing.filechooser.FileFilter;
import java.io.FileWriter;
import java.io.BufferedWriter;

public class Manager {

	private Stack stack = null;
	private ArrayList<SymbolTable> symbolTables = null;

	public Manager() {
		super();
		this.stack = new Stack();
		this.symbolTables = new ArrayList<SymbolTable>();
	}
	
	public int getOffset() {
		if(this.stack.getTopEntry() != null)
			return this.stack.getTopEntry().getOffset();
		else
			return -1;
	}
	
	public void incrementTopEntryByValue(int value) {
		this.stack.incrementTopEntryByValue(value);
	}
	
	public void addEntry(String name, SymbolTable forward) {
		this.stack.getTopTablePointer().addEntry(name, forward);
	}
	
	public void addEntry(int datatype, String name) {
		this.stack.getTopTablePointer().addEntry(datatype, name);
	}
	
	public void addEntry(String name, int value) {
		this.stack.getTopTablePointer().addEntry(name, value);
	}
	
	public void addEntry(String name, double value) {
		this.stack.getTopTablePointer().addEntry(name, value);
	}
	
	public void addEntry(String name, boolean value) {
		this.stack.getTopTablePointer().addEntry(name, value);
	}
	
	public void addEntry(int datatype, String name, boolean parameter) {
		this.stack.getTopTablePointer().addEntry(datatype, name, parameter);
	}
	
	public void addEntry(String name, int value, boolean parameter) {
		this.stack.getTopTablePointer().addEntry(name, value, parameter);
	}
	
	public void addEntry(String name, double value, boolean parameter) {
		this.stack.getTopTablePointer().addEntry(name, value, parameter);
	}
	
	public void addEntry(String name, boolean value, boolean parameter) {
		this.stack.getTopTablePointer().addEntry(name, value, parameter);
	}
	
	public SymbolTableEntry lookup(String name, boolean recursive) {
		if(this.stack.getTopTablePointer() != null) {
			return this.stack.getTopTablePointer().lookup(name, recursive);
		} else {
			return null;
		}
	}

	public void createOutput() {
		String output = "<!DOCTYPE html><html><head><link rel=\"stylesheet\" type=\"text/css\" href=\"style.css\"></head><body>";
		for (int i = 0; i < this.symbolTables.size(); i++) {
			output += "<br>" + this.symbolTables.get(i).getSymbolTableHTMLFormat();
		}
		output += "</body></html>";
		writeOutputToFile(output);
	}


	private void writeOutputToFile(String output) {
		String path = "";
	
		path += System.getProperty( "user.home" );
		
		if(path != null && path.length() > 0) {
			path += "/SymbolTables.html";
			File f = new File(path);
			if(!f.exists()) {
				try {
					f.createNewFile();
				} catch (IOException e) {
					System.out.println("Error creating the output file:\n" + e.getMessage());
				}
			}
			try{
				BufferedWriter out = new BufferedWriter(new FileWriter(path));
				out.write(output);
				out.close();
			}catch (Exception e){
				System.out.println("Error writing to output file:\n" + e.getMessage());
			}
		}
	}
	
	public void backtrack() { 
		this.stack.getTopTablePointer().calculateWidth();
		this.stack.popEntry();
	}
	
	public void createNewSymbolTable(String name) {
		SymbolTable temp = null;
		if(this.stack.getTopTablePointer() != null) {
			temp = this.stack.getTopTablePointer().createNewSymbolTable(this, this.stack.getTopTablePointer());
			this.addEntry(name, temp);
		} else {
			temp = new SymbolTable(new SymbolTableHeader(this, null));
		}
		this.stack.pushEntry(temp);
		this.symbolTables.add(temp);
	}
}
